package com.csii.activiti.server.api;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.csii.activiti.server.api.vo.Result;
import com.csii.activiti.server.core.entity.ActFlowPageData;
import com.csii.activiti.server.core.entity.db.ActCommonDataEntity;
import com.csii.activiti.server.core.query.QueryActCommonData;
import com.csii.activiti.server.core.service.FlowDataManagementService;
import com.csii.activiti.server.core.utils.URLUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;


@Api(tags="流程数据管理")
@RestController
@RequestMapping("/${activity.basic.url:activiti}/flow/dataManagement")
@Slf4j
public class FlowDataManagementController {

    private String uploadFile = "uploadFile";
    private String uploadImg = "uploadImg";

    @Autowired
    private FlowDataManagementService flowDataManagementService;


    @ApiOperation("查询数据列表")
    @GetMapping("/queryData")
    public Result<Page<Map<String,Object>>> queryData(String queryJson,
                                                      @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                                      @RequestParam(name="pageSize", defaultValue="10") Integer pageSize){
        return Result.ok(flowDataManagementService.queryData(JSONObject.parseObject(URLUtils.decode(queryJson),QueryActCommonData.class),new Page(pageNo,pageSize)));
    }

    @ApiOperation("查询页面数据")
    @GetMapping("/queryPageData")
    public Result<ActFlowPageData> queryPageData(String flowKey){
        return Result.ok(flowDataManagementService.queryPageData(flowKey));
    }

    @ApiOperation("数据导出")
    @GetMapping("/exportData")
    public void exportData(String queryJson,String showColumns, HttpServletResponse response){
        QueryActCommonData queryActCommonData = JSONObject.parseObject(URLUtils.decode(queryJson), QueryActCommonData.class);
        Page<Map<String, Object>> mapPage = flowDataManagementService.queryData(queryActCommonData,new Page(0,-1));
        ActFlowPageData actFlowPageData = flowDataManagementService.queryPageData(queryActCommonData.getFlowKey());
        List<ActCommonDataEntity> showColumnList = new ArrayList<>();
        if (showColumns != null){
            Map<String, ActCommonDataEntity> columns = actFlowPageData.getColumns().stream().collect(Collectors.toMap(ActCommonDataEntity::getColumnName, item -> item));
            for (String columnName : showColumns.split(",")) {
                ActCommonDataEntity actCommonDataEntity = columns.get(columnName);
                if (actCommonDataEntity != null){
                    showColumnList.add(actCommonDataEntity);
                }
            }
        }else{
            showColumnList = actFlowPageData.getColumns();
        }
        List<List<?>> rows = new ArrayList<>();
        List<String> titleRow = showColumnList.stream().map(ActCommonDataEntity::getColumnRemark).collect(Collectors.toList());
        rows.add(titleRow);
        List<Map<String, Object>> records = mapPage.getRecords();
        for (Map<String, Object> item : records) {
            List row = new ArrayList();
            for (ActCommonDataEntity commonDataEntity : showColumnList) {
                Object val = item.get(commonDataEntity.getColumnName());
                if (val != null && (uploadImg.equals(commonDataEntity.getElementType()) || uploadFile.equals(commonDataEntity.getElementType()))){
                    JSONArray valList = JSONObject.parseArray((String) val);
                    String nameAndUrl = valList.stream().map(jsonObj -> {
                        JSONObject jsonObject = (JSONObject) jsonObj;
                        String name = jsonObject.getString("name");
                        String url = jsonObject.getString("url");
                        return name + "（" + url + "）";
                    }).collect(Collectors.joining("；"));
                    val = nameAndUrl;
                }
                row.add(val);
            }
            rows.add(row);
        }
        ExcelWriter bigWriter = ExcelUtil.getBigWriter();
        ((SXSSFSheet)bigWriter.getSheet()).trackAllColumnsForAutoSizing();
        bigWriter.write(rows,false);
        bigWriter.autoSizeColumnAll();
        try {
            response.setHeader("content-disposition", "attachment;filename=" + new String((actFlowPageData.getFlowName()+".xlsx").getBytes("UTF-8"), "ISO-8859-1"));
            bigWriter.flush(response.getOutputStream());
            bigWriter.close();
        } catch (IOException e) {
            log.error("exportData error flowKey = "+queryActCommonData.getFlowKey() +"error : {}",e);
        }
    }
}
